"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TypeName = exports.Modifier = exports.Kind = exports.TSPoet = void 0;
/**
 * @ Author: Yoann Meclot. MSay2
 * @ Created on: 2020-08-28 09:48:25
 * @ Modified on: 2020-09-26 07:14:33
 *
 * @version 1.4
 */
/**
 * Copyright (c) 2020 MSay2, Yoann Meclot - @msay2/tspoet
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
const fs = __importStar(require("fs"));
const ArrayList_js_1 = require("../utils/ArrayList.js");
const Exceptions_js_1 = require("../utils/Exceptions.js");
const StringBuilder_js_1 = require("../utils/StringBuilder.js");
const Utils_js_1 = require("../utils/Utils.js");
const CodeWriter_js_1 = require("./CodeWriter.js");
const TSType_js_1 = require("./TSType.js");
/**
 * TSPoet is a mean to create TypeScript source files.
 *
 * The created files is Class, Enumeration, Interface and Custom Element.
 *
 * TSPoet allows you to include properties, constants, methods and your code block.
 *
 * @class TSPoet
 * @version 1.2
 */
class TSPoet {
    /**
     * Create and write a file.
     *
     * @param path The location path to generate the file.
     * @param tsType The object type to be building.
     * @throws {NullPointerException} Check if the path is null.
     * @throws {NullPointerException} Check if the TSType object is null.
     * @type {void}
     * @since 1.0
     */
    static writeFile(path, tsType) {
        if (path == undefined || path == null) {
            throw new Exceptions_js_1.NullPointerException("TSPoet must have a non-null path.");
        }
        if (tsType == undefined || tsType == null) {
            throw new Exceptions_js_1.NullPointerException("TSPoet must have a non-null TSType object.");
        }
        let name = tsType.name;
        let url = `${path}/${name}.ts`;
        fs.writeFileSync(url, "", { encoding: "utf-8" });
        if (tsType.owner instanceof TSType_js_1.ClassBuilder) {
            this.emit(url, tsType.emitClass(new CodeWriter_js_1.CodeWriter()).toString());
        }
        else if (tsType.owner instanceof TSType_js_1.EnumBuilder) {
            this.emit(url, tsType.emitEnum(new CodeWriter_js_1.CodeWriter()).toString());
        }
        else if (tsType.owner instanceof TSType_js_1.InterfaceBuilder) {
            this.emit(url, tsType.emitInterface(new CodeWriter_js_1.CodeWriter()).toString());
        }
        else if (tsType.owner instanceof TSType_js_1.CustomElementBuilder) {
            this.emit(url, tsType.emitCustomElement(new CodeWriter_js_1.CodeWriter()).toString());
        }
        else if (tsType.owner instanceof TSType_js_1.DeclarableVar) {
            this.emit(url, tsType.emitVar(new CodeWriter_js_1.CodeWriter()).toString());
        }
        else if (tsType.owner instanceof TSType_js_1.DeclarableType) {
            this.emit(url, tsType.emitType(new CodeWriter_js_1.CodeWriter()).toString());
        }
    }
    /**
     * Wrinte in file without replace the last text.
     *
     * @param path The location path to generate the file.
     * @param className The name of your file.
     * @param tsType The object type to buildind.
     * @throws {NullPointerException} Check if the path is null.
     * @throws {NullPointerException} Check if the fileName is null.
     * @throws {NullPointerException} Check if the TSType object is null.
     * @type {void}
     * @since 1.1
     */
    static writeInFile(path, fileName, tsType) {
        if (path == undefined || path == null) {
            throw new Exceptions_js_1.NullPointerException("TSPoet must have a non-null path.");
        }
        if (fileName == undefined || fileName == null) {
            throw new Exceptions_js_1.NullPointerException("TSPoet must have a non-null file name.");
        }
        if (tsType == undefined || tsType == null) {
            throw new Exceptions_js_1.NullPointerException("TSPoet must have a non-null TStype object.");
        }
        let url = `${path}/${fileName}.ts`;
        let codeWriter = new CodeWriter_js_1.CodeWriter();
        codeWriter.emit(CodeWriter_js_1.CodeWriter.NEW_LINE);
        fs.accessSync(url, fs.constants.R_OK | fs.constants.W_OK);
        if (tsType.owner instanceof TSType_js_1.ClassBuilder) {
            this.emit(url, tsType.emitClass(codeWriter).toString());
        }
        else if (tsType.owner instanceof TSType_js_1.EnumBuilder) {
            this.emit(url, tsType.emitEnum(codeWriter).toString());
        }
        else if (tsType.owner instanceof TSType_js_1.InterfaceBuilder) {
            this.emit(url, tsType.emitInterface(codeWriter).toString());
        }
        else if (tsType.owner instanceof TSType_js_1.CustomElementBuilder) {
            this.emit(url, tsType.emitCustomElement(codeWriter).toString());
        }
        else if (tsType.owner instanceof TSType_js_1.DeclarableVar) {
            this.emit(url, tsType.emitVar(codeWriter).toString());
        }
        else if (tsType.owner instanceof TSType_js_1.DeclarableType) {
            this.emit(url, tsType.emitType(codeWriter).toString());
        }
    }
    /**
     * Create a file without content.
     *
     * @param path The location path to generate the file.
     * @param name The name of the file to generate.
     * @throws {NullPointerException} Check if the path is null.
     * @throws {NullPointerException} Check if the name of file is null.
     * @type {void}
     * @since 1.2
     */
    static createFileStream(path, name) {
        if (path == undefined || path == null) {
            throw new Exceptions_js_1.NullPointerException("TSPoet must have a non-null path.");
        }
        if (name == undefined || name == null) {
            throw new Exceptions_js_1.NullPointerException("TSPoet must have a non-null name of file.");
        }
        fs.createWriteStream(`${path}/${name}`, { encoding: "utf-8", autoClose: true });
    }
    static emit(url, block) {
        fs.appendFileSync(url, `${block}`, { encoding: "utf-8" });
    }
}
exports.TSPoet = TSPoet;
/**
 * Internal enum for TSPoet.
 *
 * @ignore
 */
var Kind;
(function (Kind) {
    Kind["CLASS"] = "class";
    Kind["ENUM"] = "enum";
    Kind["INTERFACE"] = "interface";
})(Kind = exports.Kind || (exports.Kind = {}));
/**
 * Internal enum contain the all modifiers TypeScript.
 */
var Modifier;
(function (Modifier) {
    Modifier["EXPORT"] = "export";
    Modifier["PUBLIC"] = "public";
    Modifier["STATIC"] = "static";
    Modifier["PRIVATE"] = "private";
    Modifier["ABSTRACT"] = "abstract";
    Modifier["PROTECTED"] = "protected";
    Modifier["READONLY"] = "readonly";
})(Modifier = exports.Modifier || (exports.Modifier = {}));
/**
 * The TypeName class allows to you join a type of property, method, super class ...etc
 *
 * Set a default constant for join primitive type or for join a custom type set the TypeName.get method.
 * @example
 * TypeName.TYPE_VOID
 * TypeName.TYPE_BOOLEAN
 * TypeName.TYPE_STRING
 * TypeName.TYPE_NUMBER
 * TypeName.TYPE_ANY
 * TypeName.get("MyType")
 *
 * @class TypeName
 * @version 1.0
 */
class TypeName {
    constructor(name) {
        this.nameType = name;
    }
    /**
     * Get a custom name object.
     *
     * @param name The name of the object.
     * @throws {NullPointerException} Check if the name is null.
     * @throws {IllegalStateException} Use TypeName.transtypeTo method.
     * @type {TypeName}
     * @since 1.0
     */
    static get(name) {
        return new TypeName(Utils_js_1.Utils.checkNotNull(name, "TypeName must have a non-null name."));
    }
    /**
     * Transtype the object type.
     *
     * @param args The names of the objects.
     * @type {TypeName}
     * @since 1.0
     */
    transtypeTo(...args) {
        if (args.length == 0) {
            return this;
        }
        let transtypeBuilder = new StringBuilder_js_1.StringBuilder();
        let cloneArgs = ArrayList_js_1.Arrays.asList(Utils_js_1.Utils.checkNotNull(args, "TypeName must have a non-null transtype argument."));
        transtypeBuilder.append("<");
        for (let entry of cloneArgs.entries()) {
            transtypeBuilder.append(entry.getValue()).append((entry.isLastData() ? "" : ", "));
        }
        transtypeBuilder.append(">");
        this.nameType += transtypeBuilder.toString();
        return this;
    }
    getName() {
        return this.nameType;
    }
}
exports.TypeName = TypeName;
TypeName.TYPE_VOID = TypeName.get("void");
TypeName.TYPE_BOOLEAN = TypeName.get("boolean");
TypeName.TYPE_STRING = TypeName.get("string");
TypeName.TYPE_NUMBER = TypeName.get("number");
TypeName.TYPE_ANY = TypeName.get("any");
//# sourceMappingURL=TSPoet.js.map